﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
using System.Net;
using System.IO;

namespace NuGet.Enterprise.Server.Xml
{
    public class XmlPackageReader
        : XmlWrappingReader
    {
        private const string FilterFormat = "$filter=(((Id ne null) and substringof('{0}',tolower(Id))) or ((Description ne null) and substringof('{0}',tolower(Description)))) or ((Tags ne null) and substringof(' {0} ',tolower(Tags)))";

        public static int GetCount(string serviceUri, string filter)
        {
            var uri = BuildCountUri(serviceUri, filter);
            var req = (HttpWebRequest) HttpWebRequest.Create(uri);

            using (var res = (HttpWebResponse) req.GetResponse())
            {
                int count = int.MaxValue;

                if (res.StatusCode == HttpStatusCode.OK)
                {
                    var content = res.GetResponseStream().ReadToEnd();

                    if (!int.TryParse(content, out count))
                    {
                        count = int.MaxValue;
                    }
                }

                return count;
            }
        }

        private static string BuildCountUri(string serviceUri, string filter)
        {
            var uri = serviceUri + (serviceUri.EndsWith("/") ? string.Empty : "/") + "$count";

            if (!string.IsNullOrEmpty(filter))
            {
                uri += "?" + FilterFormat.FormatInvariant(filter.ToLowerInvariant());
            }

            return uri;
        }

        private static string BuildQueryUri(string serviceUri, string filter, int pageIndex, int pageSize)
        {
            var uri = serviceUri + "?$orderby=DownloadCount desc,Id&$skip={0}&$top={1}".FormatInvariant((pageIndex * pageSize), pageSize);

            if (!string.IsNullOrEmpty(filter))
            {
                uri += "&" + FilterFormat.FormatInvariant(filter.ToLowerInvariant());
            }

            return uri;
        }

        public XmlPackageReader(string serviceUri, string filter, int pageIndex, int pageSize)
            : base(XmlReader.Create(BuildQueryUri(serviceUri, filter, Math.Max(pageIndex, 0), Math.Max(pageSize, 1))))
        { }
    }
}